home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / body.cpp < prev    next >
C/C++ Source or Header  |  2000-01-06  |  99KB  |  2,346 lines

  1. // $Id: body.cpp,v 1.28 2000/01/06 08:24:30 lord Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10.  
  11. #include "config.h"
  12. #include <assert.h>
  13. #include "semantic.h"
  14. #include "control.h"
  15.  
  16. void Semantic::ProcessBlockStatements(AstBlock *block_body)
  17. {
  18.     //
  19.     // An empty block that is not a switch block can complete normally
  20.     // iff it is reachable. A nonempty block that is not a switch
  21.     // block can complete normally iff the last statement in it can
  22.     // complete normally.
  23.     //
  24.     if (block_body -> NumStatements() == 0)
  25.          block_body -> can_complete_normally = block_body -> is_reachable;
  26.     else
  27.     {
  28.         //
  29.         // The first statement in a nonempty block that is not a
  30.         // switch block is reachable iff the block is reachable.
  31.         // Every other statement S in a nonempty block that is not a
  32.         // switch block is reachable iff the statement preceeding S
  33.         // can complete normally.
  34.         //
  35.         AstStatement *statement = (AstStatement *) block_body -> Statement(0);
  36.         statement -> is_reachable = block_body -> is_reachable;
  37.         AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  38.         ProcessStatement(statement);
  39.         for (int i = 1; i < block_body -> NumStatements(); i++)
  40.         {
  41.             AstStatement *previous_statement = statement;
  42.             statement = (AstStatement *) block_body -> Statement(i);
  43.             statement -> is_reachable = previous_statement -> can_complete_normally;
  44.             if (! statement -> is_reachable && (first_unreachable_statement == NULL))
  45.                 first_unreachable_statement = statement;
  46.  
  47.             ProcessStatement(statement);
  48.         }
  49.  
  50.         if (statement -> can_complete_normally)
  51.             block_body -> can_complete_normally = true;
  52.  
  53.         //
  54.         // If we have one or more unreachable statements that are contained in a
  55.         // reachable block then issue message. (If the enclosing block is not reachable
  56.         // the message will be issued later for the enclosing block.)
  57.         //
  58.         if (first_unreachable_statement && LocalBlockStack().TopBlock() -> is_reachable)
  59.         {
  60.             if (first_unreachable_statement == statement)
  61.             {
  62.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  63.                                statement -> LeftToken(),
  64.                                statement -> RightToken());
  65.             }
  66.             else
  67.             {
  68.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  69.                                first_unreachable_statement -> LeftToken(),
  70.                                statement -> RightToken());
  71.             }
  72.         }
  73.  
  74.         //
  75.         // If an enclosed block has a higher max_variable_index than the current block,
  76.         // update max_variable_index in the current_block, accordingly.
  77.         //
  78.         BlockSymbol *block = block_body -> block_symbol;
  79.         if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  80.             block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  81.     }
  82.  
  83.     return;
  84. }
  85.  
  86.  
  87. void Semantic::ProcessBlock(Ast *stmt)
  88. {
  89.     AstBlock *block_body = (AstBlock *) stmt;
  90.  
  91.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  92.  
  93.     //
  94.     // Guess that the number of elements will not exceed the number of statements + 3. The +3 takes into account
  95.     // one label + one ForInit declaration and one extra something else.
  96.     //
  97.     int table_size = block_body -> NumStatements() + 3;
  98.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  99.     //
  100.     // enclosing_block is not present only when we are processing the block of a static initializer
  101.     //
  102.     block -> max_variable_index = (enclosing_block ? enclosing_block -> block_symbol -> max_variable_index : 1);
  103.     LocalSymbolTable().Push(block -> Table());
  104.  
  105.     block_body -> block_symbol = block;
  106.     block_body -> nesting_level = LocalBlockStack().Size();
  107.     LocalBlockStack().Push(block_body);
  108.  
  109.     //
  110.     // Note that in constructing the Ast, the parser encloses each
  111.     // labeled statement in its own block. Therefore the declaration
  112.     // of this label will not conflict with the declaration of another
  113.     // label with the same name declared at the same nesting level.
  114.     //
  115.     // For example, the following sequence of statements is legal:
  116.     //
  117.     //     l: a = b;
  118.     //     l: b = c;
  119.     //
  120.     for (int i = 0; i < block_body -> NumLabels(); i++)
  121.     {
  122.         NameSymbol *name_symbol = lex_stream -> NameSymbol(block_body -> Label(i));
  123.         Symbol *symbol = NULL;
  124.         for (SemanticEnvironment *env = state_stack.Top(); env; env = env -> previous)
  125.         {
  126.             symbol = env -> symbol_table.FindLabelSymbol(name_symbol);
  127.             if (symbol)
  128.                 break;
  129.         }
  130.  
  131.         if (symbol)
  132.         {
  133.             ReportSemError(SemanticError::DUPLICATE_LABEL,
  134.                            block_body -> Label(i),
  135.                            block_body -> Label(i),
  136.                            name_symbol -> Name());
  137.         }
  138.         else
  139.         {
  140.             LabelSymbol *label = LocalSymbolTable().Top() -> InsertLabelSymbol(name_symbol);
  141.             label -> block = block_body;
  142.             label -> nesting_level = block_body -> nesting_level;
  143.         }
  144.     }
  145.  
  146.     ProcessBlockStatements(block_body);
  147.  
  148.     LocalBlockStack().Pop();
  149.     LocalSymbolTable().Pop();
  150.  
  151.     //
  152.     // Update the information for the block that immediately encloses the current block.
  153.     //
  154.     if (enclosing_block)
  155.     {
  156.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  157.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  158.     }
  159.  
  160.     block -> CompressSpace(); // space optimization
  161.  
  162.     return;
  163. }
  164.  
  165.  
  166. void Semantic::ProcessLocalVariableDeclarationStatement(Ast *stmt)
  167. {
  168.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  169.  
  170.     AstArrayType *array_type = local_decl -> type -> ArrayTypeCast();
  171.     Ast *actual_type = (array_type ? array_type -> type : local_decl -> type);
  172.  
  173.     AccessFlags access_flags = ProcessLocalModifiers(local_decl);
  174.  
  175.     AstPrimitiveType *primitive_type = actual_type -> PrimitiveTypeCast();
  176.     TypeSymbol *field_type = (primitive_type ? field_type = FindPrimitiveType(primitive_type) : MustFindType(actual_type));
  177.  
  178.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  179.     {
  180.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  181.         AstVariableDeclaratorId *name = variable_declarator -> variable_declarator_name;
  182.         NameSymbol *name_symbol = lex_stream -> NameSymbol(name -> identifier_token);
  183.  
  184. //
  185. // TODO: Confirm that this new test is indeed the case. In 1.0, only the more restricted test below was necessary.
  186. //
  187. //        if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  188. //        {
  189. //            ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  190. //                           name -> identifier_token,
  191. //                           name -> identifier_token,
  192. //                           name_symbol -> Name());
  193. //        }
  194. //
  195.         SemanticEnvironment *where_found;
  196.         Tuple<VariableSymbol *> variables_found(2);
  197.         SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(), name_symbol, name -> identifier_token);
  198.         VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  199.         if (symbol && symbol -> IsLocal())
  200.         {
  201.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  202.                            name -> identifier_token,
  203.                            name -> identifier_token,
  204.                            name_symbol -> Name());
  205.         }
  206.         else
  207.         {
  208.             symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  209.             variable_declarator -> symbol = symbol;
  210.  
  211.             int num_dimensions = (array_type ? array_type -> NumBrackets() : 0) + name -> NumBrackets();
  212.             if (num_dimensions == 0)
  213.                  symbol -> SetType(field_type);
  214.             else symbol -> SetType(field_type -> GetArrayType((Semantic *) this, num_dimensions));
  215.             symbol -> SetFlags(access_flags);
  216.             symbol -> SetOwner(ThisMethod());
  217.             symbol -> declarator = variable_declarator;
  218.             BlockSymbol *block = LocalBlockStack().TopBlock() -> block_symbol;
  219.             symbol -> SetLocalVariableIndex(block -> max_variable_index++); // Assigning a local_variable_index to a variable
  220.                                                                             // also marks it complete as a side-effect.
  221.             if (control.IsDoubleWordType(symbol -> Type()))
  222.                 block -> max_variable_index++;
  223.  
  224.             if (variable_declarator -> variable_initializer_opt)
  225.                  ProcessVariableInitializer(variable_declarator);
  226.         }
  227.     }
  228.  
  229.     //
  230.     // A local variable declaration statement can complete normally
  231.     // iff it is reachable.
  232.     //
  233.     local_decl -> can_complete_normally = local_decl -> is_reachable;
  234.  
  235.     return;
  236. }
  237.  
  238.  
  239. void Semantic::ProcessExpressionStatement(Ast *stmt)
  240. {
  241.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  242.  
  243.     ProcessExpression(expression_statement -> expression);
  244.  
  245.     //
  246.     // An expression statement can complete normally iff it is reachable.
  247.     //
  248.     expression_statement -> can_complete_normally = expression_statement -> is_reachable;
  249.  
  250.     return;
  251. }
  252.  
  253.  
  254. void Semantic::ProcessSynchronizedStatement(Ast *stmt)
  255. {
  256.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  257.  
  258.     ProcessExpression(synchronized_statement -> expression);
  259.  
  260.     synchronized_statement -> block -> is_reachable = synchronized_statement -> is_reachable;
  261.  
  262.     if (synchronized_statement -> expression -> Type() -> Primitive())
  263.     {
  264.         ReportSemError(SemanticError::TYPE_NOT_REFERENCE,
  265.                        synchronized_statement -> expression -> LeftToken(),
  266.                        synchronized_statement -> expression -> RightToken(),
  267.                        synchronized_statement -> expression -> Type() -> Name());
  268.     }
  269.  
  270.     AstBlock *enclosing_block = LocalBlockStack().TopBlock(),
  271.              *block_body = synchronized_statement -> block;
  272.  
  273.     //
  274.     // "synchronized" blocks require two more local variable slots for synchronization,
  275.     // plus one extra variable slot if the containing method returns a value, plus an
  276.     // additional slot if the value returned is double or long.
  277.     //
  278.     BlockSymbol *enclosing_block_symbol = enclosing_block -> block_symbol;
  279.     if (enclosing_block_symbol -> try_or_synchronized_variable_index == 0) // first such statement encountered in enclosing block?
  280.     {
  281.         enclosing_block_symbol -> try_or_synchronized_variable_index = enclosing_block_symbol -> max_variable_index;
  282.         enclosing_block_symbol -> max_variable_index += 2;
  283.         if (ThisMethod() -> Type() != control.void_type)
  284.         {
  285.              if (control.IsDoubleWordType(ThisMethod() -> Type()))
  286.                   enclosing_block_symbol -> max_variable_index += 2;
  287.              else enclosing_block_symbol -> max_variable_index += 1;
  288.         }
  289.     }
  290.  
  291.     //
  292.     // Guess that the number of elements will not exceed the number of statements + 3.
  293.     //
  294.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 3);
  295.     block -> max_variable_index = enclosing_block_symbol -> max_variable_index;
  296.     LocalSymbolTable().Push(block -> Table());
  297.  
  298.     block_body -> block_symbol = block;
  299.     block_body -> nesting_level = LocalBlockStack().Size();
  300.     LocalBlockStack().Push(block_body);
  301.  
  302.     ProcessBlockStatements(block_body);
  303.  
  304.     LocalBlockStack().Pop();
  305.     LocalSymbolTable().Pop();
  306.  
  307.     if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  308.         LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  309.  
  310.     //
  311.     // If the synchronized_statement is enclosed in a loop and it contains a reachable continue statement
  312.     // then it may have already been marked as "can complete normally";
  313.     //
  314.     synchronized_statement -> can_complete_normally = synchronized_statement -> can_complete_normally ||
  315.                                                       synchronized_statement -> block -> can_complete_normally;
  316.  
  317.     block -> CompressSpace(); // space optimization
  318.  
  319.     return;
  320. }
  321.  
  322.  
  323. void Semantic::ProcessIfStatement(Ast *stmt)
  324. {
  325.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  326.  
  327.     ProcessExpression(if_statement -> expression);
  328.  
  329.     if (if_statement -> expression -> Type() != control.no_type &&
  330.         if_statement -> expression -> Type() != control.boolean_type)
  331.     {
  332.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  333.                        if_statement -> expression -> LeftToken(),
  334.                        if_statement -> expression -> RightToken(),
  335.                        if_statement -> expression -> Type() -> Name());
  336.     }
  337.  
  338.     //
  339.     // Recall that the parser ensures that the statements that appear in an if-statement
  340.     // (both the true and false statement) are enclosed in a block.
  341.     //
  342.     if_statement -> true_statement -> is_reachable = if_statement -> is_reachable;
  343.     ProcessBlock(if_statement -> true_statement);
  344.  
  345.     if (if_statement -> false_statement_opt)
  346.     {
  347.         if_statement -> false_statement_opt -> is_reachable = if_statement -> is_reachable;
  348.         ProcessBlock(if_statement -> false_statement_opt);
  349.  
  350.         //
  351.         // If the if_statement is enclosed in a loop and it contains a reachable continue statement
  352.         // then it may have already been marked as "can complete normally";
  353.         //
  354.         if_statement -> can_complete_normally = if_statement -> can_complete_normally ||
  355.                                                 if_statement -> true_statement -> can_complete_normally ||
  356.                                                 if_statement -> false_statement_opt -> can_complete_normally;
  357.     }
  358.     else if_statement -> can_complete_normally = if_statement -> is_reachable;
  359.  
  360.     return;
  361. }
  362.  
  363.  
  364. void Semantic::ProcessWhileStatement(Ast *stmt)
  365. {
  366.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  367.  
  368.     //
  369.     // Recall that each while statement is enclosed in a unique block by the parser
  370.     //
  371.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  372.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  373.  
  374.     AstStatement *enclosed_statement = while_statement -> statement;
  375.     enclosed_statement -> is_reachable = while_statement -> is_reachable;
  376.  
  377.     ProcessExpression(while_statement -> expression);
  378.     if (while_statement -> expression -> Type() == control.boolean_type)
  379.     {
  380.         if (while_statement -> expression -> IsConstant())
  381.         {
  382.             IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  383.             if (! literal -> value)
  384.             {
  385.                  if (while_statement -> is_reachable)
  386.                      while_statement -> can_complete_normally = true;
  387.                  enclosed_statement -> is_reachable = false;
  388.             }
  389.         }
  390.         else if (while_statement -> is_reachable)
  391.              while_statement -> can_complete_normally = true;
  392.     }
  393.     else if (while_statement -> expression -> Type() != control.no_type)
  394.     {
  395.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  396.                        while_statement -> expression -> LeftToken(),
  397.                        while_statement -> expression -> RightToken(),
  398.                        while_statement -> expression -> Type() -> Name());
  399.     }
  400.  
  401.     ProcessStatement(enclosed_statement);
  402.  
  403.     if ((! enclosed_statement -> is_reachable) && (while_statement -> is_reachable))
  404.     {
  405.         ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  406.                        enclosed_statement -> LeftToken(),
  407.                        enclosed_statement -> RightToken());
  408.     }
  409.  
  410.     //
  411.     // If the while statement contained a reachable break statement,
  412.     // then the while statement can complete normally. It is marked
  413.     // here only for completeness, as marking the enclosing block is
  414.     // enough to propagate the proper information upward.
  415.     //
  416.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  417.     if (block_body -> can_complete_normally)
  418.         while_statement -> can_complete_normally = true;
  419.  
  420.     BreakableStatementStack().Pop();
  421.     ContinuableStatementStack().Pop();
  422.  
  423.     return;
  424. }
  425.  
  426.  
  427. void Semantic::ProcessForStatement(Ast *stmt)
  428. {
  429.     AstForStatement *for_statement = (AstForStatement *) stmt;
  430.  
  431.     //
  432.     // Note that in constructing the Ast, the parser encloses each
  433.     // for-statement whose for-init-statements starts with a local
  434.     // variable declaration in its own block. Therefore a redeclaration
  435.     // of another local variable with the same name in a different loop
  436.     // at the same nesting level will not cause any conflict.
  437.     //
  438.     // For example, the following sequence of statements is legal:
  439.     //
  440.     //     for (int i = 0; i < 10; i++);
  441.     //     for (int i = 10; i < 20; i++);
  442.     //
  443.     for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  444.         ProcessStatement(for_statement -> ForInitStatement(i));
  445.  
  446.     //
  447.     // Recall that each for statement is enclosed in a unique block by the parser
  448.     //
  449.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  450.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  451.  
  452.     //
  453.     // Assume that if the for_statement is reachable then its
  454.     // contained statement is also reachable. If it turns out that the
  455.     // condition (end) expression is a constant FALSE expression we will
  456.     // change the assumption...
  457.     //
  458.     AstStatement *enclosed_statement = for_statement -> statement;
  459.     enclosed_statement -> is_reachable = for_statement -> is_reachable;
  460.  
  461.     if (for_statement -> end_expression_opt)
  462.     {
  463.         ProcessExpression(for_statement -> end_expression_opt);
  464.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type)
  465.         {
  466.             if (for_statement -> end_expression_opt -> IsConstant())
  467.             {
  468.                 IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  469.                 if (! literal -> value)
  470.                 {
  471.                      if (for_statement -> is_reachable)
  472.                          for_statement -> can_complete_normally = true;
  473.                      enclosed_statement -> is_reachable = false;
  474.                 }
  475.             }
  476.             else if (for_statement -> is_reachable)
  477.                  for_statement -> can_complete_normally = true;
  478.         }
  479.         else if (for_statement -> end_expression_opt -> Type() != control.no_type)
  480.         {
  481.             ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  482.                            for_statement -> end_expression_opt -> LeftToken(),
  483.                            for_statement -> end_expression_opt -> RightToken(),
  484.                            for_statement -> end_expression_opt -> Type() -> Name());
  485.         }
  486.     }
  487.  
  488.     ProcessStatement(enclosed_statement);
  489.  
  490.     if ((! enclosed_statement -> is_reachable) && (for_statement -> is_reachable))
  491.     {
  492.         ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  493.                        enclosed_statement -> LeftToken(),
  494.                        enclosed_statement -> RightToken());
  495.     }
  496.  
  497.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  498.         ProcessExpressionStatement(for_statement -> ForUpdateStatement(j));
  499.  
  500.     //
  501.     // If the for statement contained a reachable break statement,
  502.     // then the for statement can complete normally. It is marked
  503.     // here only for completeness, as marking the enclosing block is
  504.     // enough to propagate the proper information upward.
  505.     //
  506.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  507.     if (block_body -> can_complete_normally)
  508.         for_statement -> can_complete_normally = true;
  509.  
  510.     BreakableStatementStack().Pop();
  511.     ContinuableStatementStack().Pop();
  512.  
  513.     return;
  514. }
  515.  
  516.  
  517. void Semantic::ProcessSwitchStatement(Ast *stmt)
  518. {
  519.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  520.  
  521.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  522.  
  523.     //
  524.     // We estimate a size for the switch symbol table based on the number of lines in it.
  525.     //
  526.     AstBlock *block_body = switch_statement -> switch_block;
  527.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol();
  528.     block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  529.     LocalSymbolTable().Push(block -> Table());
  530.  
  531.     block_body -> block_symbol = block;
  532.     block_body -> nesting_level = LocalBlockStack().Size();
  533.     LocalBlockStack().Push(block_body);
  534.     BreakableStatementStack().Push(block_body);
  535.  
  536.     ProcessExpression(switch_statement -> expression);
  537.     TypeSymbol *type = switch_statement -> expression -> Type();
  538.  
  539.     if (type != control.int_type  && type != control.short_type &&
  540.         type != control.char_type && type != control.byte_type  && type != control.no_type)
  541.     {
  542.         ReportSemError(SemanticError::TYPE_NOT_VALID_FOR_SWITCH,
  543.                        switch_statement -> expression -> LeftToken(),
  544.                        switch_statement -> expression -> RightToken(),
  545.                        type -> ContainingPackage() -> PackageName(),
  546.                        type -> ExternalName());
  547.     }
  548.  
  549.     switch_statement -> default_case.switch_block_statement = NULL;
  550.  
  551.     //
  552.     // Count the number case labels in this switch statement
  553.     //
  554.     int num_case_labels = 0;
  555.     for (int i = 0; i < block_body -> NumStatements(); i++)
  556.     {
  557.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  558.         num_case_labels += switch_block_statement -> NumSwitchLabels();
  559.     }
  560.     switch_statement -> AllocateCases(num_case_labels);
  561.  
  562.     //
  563.     // A switch block is reachable iff its switch statement is reachable.
  564.     //
  565.     block_body -> is_reachable = switch_statement -> is_reachable;
  566.     for (int j = 0; j < block_body -> NumStatements(); j++)
  567.     {
  568.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(j);
  569.  
  570.         for (int k = 0; k < switch_block_statement -> NumSwitchLabels(); k++)
  571.         {
  572.             AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(k) -> CaseLabelCast();
  573.  
  574.             if (case_label)
  575.             {
  576.                 ProcessExpression(case_label -> expression);
  577.  
  578.                 if (case_label -> expression -> Type() != control.no_type)
  579.                 {
  580.                     if (! case_label -> expression -> IsConstant())
  581.                     {
  582.                         ReportSemError(SemanticError::EXPRESSION_NOT_CONSTANT,
  583.                                        case_label -> expression -> LeftToken(),
  584.                                        case_label -> expression -> RightToken());
  585.                         case_label -> expression -> symbol = control.no_type;
  586.                     }
  587.                     else if (type != control.no_type)
  588.                     {
  589.                         if (CanAssignmentConvert(type, case_label -> expression))
  590.                         {
  591.                             if (case_label -> expression -> Type() != type)
  592.                                 case_label -> expression = ConvertToType(case_label -> expression, type);
  593.  
  594.                             case_label -> map_index = switch_statement -> NumCases();
  595.  
  596.                             CaseElement *case_element = compilation_unit -> ast_pool -> GenCaseElement();
  597.                             switch_statement -> AddCase(case_element);
  598.  
  599.                             case_element -> expression = case_label -> expression;
  600.                             case_element -> switch_block_statement = switch_block_statement;
  601.                             case_element -> index = case_label -> map_index; // use this index to keep sort stable !
  602.                         }
  603.                         else if (case_label -> expression -> Type() == control.int_type &&
  604.                                  ! IsIntValueRepresentableInType(case_label -> expression, type))
  605.                         {
  606.                             IntToWstring value(((IntLiteralValue *) (case_label -> expression -> value)) -> value);
  607.  
  608.                             ReportSemError(SemanticError::VALUE_NOT_REPRESENTABLE_IN_SWITCH_TYPE,
  609.                                            case_label -> expression -> LeftToken(),
  610.                                            case_label -> expression -> RightToken(),
  611.                                            value.String(),
  612.                                            type -> Name());
  613.                         }
  614.                         else
  615.                         {
  616.                             ReportSemError(SemanticError::TYPE_NOT_CONVERTIBLE_TO_SWITCH_TYPE,
  617.                                            case_label -> expression -> LeftToken(),
  618.                                            case_label -> expression -> RightToken(),
  619.                                            case_label -> expression -> Type() -> Name(),
  620.                                            type -> Name());
  621.                         }
  622.                     }
  623.                 }
  624.             }
  625.             else if (switch_statement -> default_case.switch_block_statement == NULL)
  626.                 switch_statement -> default_case.switch_block_statement = switch_block_statement;
  627.             else
  628.             {
  629.                 ReportSemError(SemanticError::MULTIPLE_DEFAULT_LABEL,
  630.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(k)) -> LeftToken(),
  631.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(k)) -> RightToken());
  632.             }
  633.         }
  634.  
  635.         //
  636.         // The parser ensures that a switch block statement always has one statement.
  637.         // When a switch block ends with a sequence of switch labels that are not followed
  638.         // by any executable statements, an artificial "empty" statement is added by the parser.
  639.         //
  640.         assert(switch_block_statement -> NumStatements() > 0);
  641.  
  642.         //
  643.         // A statement in a switch block is reachable iff its
  644.         // switch statement is reachable and at least one of the
  645.         // following is true:
  646.         //
  647.         // . it bears a case or default label
  648.         // . there is a statement preceeding it in the switch block and that
  649.         // preceeding  statement can compile normally.
  650.         //
  651.         AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(0);
  652.         statement -> is_reachable = switch_statement -> is_reachable;
  653.         AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  654.         ProcessStatement(statement);
  655.         for (int j = 1; j < switch_block_statement -> NumStatements(); j++)
  656.         {
  657.             AstStatement *previous_statement = statement;
  658.             statement = (AstStatement *) switch_block_statement -> Statement(j);
  659.             if (switch_statement -> is_reachable)
  660.             {
  661.                 statement -> is_reachable = previous_statement -> can_complete_normally;
  662.                 if ((! statement -> is_reachable) && (first_unreachable_statement == NULL))
  663.                     first_unreachable_statement = statement;
  664.             }
  665.  
  666.             ProcessStatement(statement);
  667.         }
  668.  
  669.         if (first_unreachable_statement)
  670.         {
  671.             if (first_unreachable_statement == statement)
  672.             {
  673.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  674.                                statement -> LeftToken(),
  675.                                statement -> RightToken());
  676.             }
  677.             else
  678.             {
  679.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  680.                                first_unreachable_statement -> LeftToken(),
  681.                                statement -> RightToken());
  682.             }
  683.         }
  684.     }
  685.  
  686.     //
  687.     // A switch statement can complete normally iff at least one of the
  688.     // following is true:
  689.     //
  690.     // . there is a reachable break statement that exits the switch
  691.     //   statement. (See ProcessBreakStatement)
  692.     // . the switch block is empty or contains only switch labels
  693.     //   //
  694.     //   // TODO: This statement seems to be erroneous. The proper statement
  695.     //   //       as implemented here is:
  696.     //   //
  697.     //   //           . the switch block is empty or contains only case labels
  698.     //   //
  699.     // . there is at least one switch label after the last switch block
  700.     //   statement group.
  701.     // . the last statement in the switch block can complete normally
  702.     //
  703.     if (block_body -> can_complete_normally)
  704.         switch_statement -> can_complete_normally = true;
  705.     else if (switch_statement -> default_case.switch_block_statement == NULL)
  706.         switch_statement -> can_complete_normally = true;
  707.     else
  708.     {
  709.         AstSwitchBlockStatement *last_switch_block_statement = (AstSwitchBlockStatement *)
  710.                                                                block_body -> Statement(block_body -> NumStatements() - 1);
  711.  
  712.         assert(last_switch_block_statement -> NumStatements() > 0);
  713.  
  714.         AstStatement *last_statement = (AstStatement *)
  715.                                        last_switch_block_statement -> Statement(last_switch_block_statement -> NumStatements() - 1);
  716.         if (last_statement -> can_complete_normally)
  717.             switch_statement -> can_complete_normally = true;
  718.     }
  719.  
  720.     switch_statement -> SortCases();
  721.     for (int k = 1; k < switch_statement -> NumCases(); k++)
  722.     {
  723.         if (switch_statement -> Case(k) -> Value() == switch_statement -> Case(k - 1) -> Value())
  724.         {
  725.             IntToWstring value(switch_statement -> Case(k) -> Value());
  726.  
  727.             ReportSemError(SemanticError::DUPLICATE_CASE_VALUE,
  728.                            switch_statement -> Case(k) -> expression -> LeftToken(),
  729.                            switch_statement -> Case(k) -> expression -> RightToken(),
  730.                            value.String());
  731.         }
  732.     }
  733.  
  734.     //
  735.     // If an enclosed block has a higher max_variable_index than the current block,
  736.     // update max_variable_index in the current_block, accordingly.
  737.     // Also, update the information for the block that immediately encloses the current block.
  738.     //
  739.     if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  740.         block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  741.  
  742.     BreakableStatementStack().Pop();
  743.     LocalBlockStack().Pop();
  744.     LocalSymbolTable().Pop();
  745.  
  746.     if (enclosing_block)
  747.     {
  748.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  749.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  750.     }
  751.  
  752.     block -> CompressSpace(); // space optimization
  753.  
  754.     return;
  755. }
  756.  
  757.  
  758. void Semantic::ProcessDoStatement(Ast *stmt)
  759. {
  760.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  761.  
  762.     //
  763.     // Recall that each Do statement is enclosed in a unique block by the parser
  764.     //
  765.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  766.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  767.  
  768.     AstStatement *enclosed_statement = do_statement -> statement;
  769.     enclosed_statement -> is_reachable = do_statement -> is_reachable;
  770.  
  771.     ProcessStatement(enclosed_statement);
  772.  
  773.     ProcessExpression(do_statement -> expression);
  774.  
  775.     IntLiteralValue *literal = NULL;
  776.     if (do_statement -> expression -> Type() == control.boolean_type)
  777.     {
  778.         if (do_statement -> expression -> IsConstant())
  779.             literal = (IntLiteralValue *) do_statement -> expression -> value;
  780.     }
  781.     else if (do_statement -> expression -> Type() != control.no_type)
  782.     {
  783.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  784.                        do_statement -> expression -> LeftToken(),
  785.                        do_statement -> expression -> RightToken(),
  786.                        do_statement -> expression -> Type() -> Name());
  787.     }
  788.  
  789.     //
  790.     // A do statement can complete normally, iff at least one of the following is true:
  791.     //     1. The contained statement can complete normally and the condition expression
  792.     //        is not a constant expression with the value true
  793.     //     2. There is a reachable break statement that exits the do statement
  794.     //        (This condition is true is the block that immediately encloses this do statement
  795.     //         can complete normally. See ProcessBreakStatement)
  796.     //
  797.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  798.     do_statement -> can_complete_normally = (enclosed_statement -> can_complete_normally && ((! literal) || literal -> value == 0)) ||
  799.                                             block_body -> can_complete_normally;
  800.  
  801.     BreakableStatementStack().Pop();
  802.     ContinuableStatementStack().Pop();
  803.  
  804.     return;
  805. }
  806.  
  807.  
  808. void Semantic::ProcessBreakStatement(Ast *stmt)
  809. {
  810.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  811.  
  812.     //
  813.     // Recall that it is possible to break out of any labeled statement even if it is not a
  814.     // do, for, while or switch statement.
  815.     //
  816.     if (break_statement -> identifier_token_opt)
  817.     {
  818.         NameSymbol *name_symbol = lex_stream -> NameSymbol(break_statement -> identifier_token_opt);
  819.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  820.  
  821.         if (label_symbol)
  822.         {
  823.             break_statement -> nesting_level = label_symbol -> nesting_level;
  824.             AstBlock *block_body = label_symbol -> block;
  825.             //
  826.             // A labeled statement can complete normally if there is a
  827.             // reachable break statement that exits the labeled statement.
  828.             //
  829.             if (block_body && break_statement -> is_reachable)
  830.                 block_body -> can_complete_normally = true;
  831.         }
  832.         else
  833.         {
  834.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  835.             break_statement -> nesting_level = block_body -> nesting_level;
  836.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  837.                            break_statement -> identifier_token_opt,
  838.                            break_statement -> identifier_token_opt,
  839.                            lex_stream -> NameString(break_statement -> identifier_token_opt));
  840.         }
  841.     }
  842.     else
  843.     {
  844.         AstBlock *block_body = (AstBlock *) (BreakableStatementStack().Size() > 0 ? BreakableStatementStack().Top()
  845.                                                                                   : LocalBlockStack().TopBlock());
  846.         break_statement -> nesting_level = block_body -> nesting_level;
  847.         if (BreakableStatementStack().Size() > 0)
  848.         {
  849.             if (break_statement -> is_reachable)
  850.                 block_body -> can_complete_normally = true;
  851.         }
  852.         else ReportSemError(SemanticError::MISPLACED_BREAK_STATEMENT,
  853.                             break_statement -> LeftToken(),
  854.                             break_statement -> RightToken());
  855.     }
  856.  
  857.     return;
  858. }
  859.  
  860.  
  861. void Semantic::ProcessContinueStatement(Ast *stmt)
  862. {
  863.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  864.  
  865.     //
  866.     // The loop statement that is to be continued.
  867.     //
  868.     Ast *loop_statement = NULL;
  869.  
  870.     if (ContinuableStatementStack().Size() <= 0)
  871.     {
  872.         ReportSemError(SemanticError::MISPLACED_CONTINUE_STATEMENT,
  873.                        continue_statement -> LeftToken(),
  874.                        continue_statement -> RightToken());
  875.     }
  876.     else if (continue_statement -> identifier_token_opt)
  877.     {
  878.         NameSymbol *name_symbol = lex_stream -> NameSymbol(continue_statement -> identifier_token_opt);
  879.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  880.  
  881.         if (label_symbol)
  882.         {
  883.             continue_statement -> nesting_level = label_symbol -> nesting_level;
  884.  
  885.             assert(label_symbol -> block -> NumStatements() > 0);
  886.  
  887.             loop_statement = label_symbol -> block -> Statement(0);
  888.         }
  889.         else
  890.         {
  891.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  892.             continue_statement -> nesting_level = block_body -> nesting_level;
  893.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  894.                            continue_statement -> identifier_token_opt,
  895.                            continue_statement -> identifier_token_opt,
  896.                            lex_stream -> NameString(continue_statement -> identifier_token_opt));
  897.         }
  898.     }
  899.     else
  900.     {
  901.         AstBlock *block_body = (AstBlock *) ContinuableStatementStack().Top();
  902.         loop_statement = block_body -> Statement(0);
  903.         continue_statement -> nesting_level = block_body -> nesting_level;
  904.     }
  905.  
  906.     //
  907.     // If this is a valid continue statement, it is associated with a loop statement.
  908.     // Since the loop can be continued, its enclosed statement "can complete normally".
  909.     //
  910.     if (loop_statement)
  911.     {
  912.         AstDoStatement *do_statement = loop_statement -> DoStatementCast();
  913.         AstForStatement *for_statement = loop_statement -> ForStatementCast();
  914.         AstWhileStatement *while_statement = loop_statement -> WhileStatementCast();
  915.  
  916.         AstStatement *enclosed_statement = (do_statement ? do_statement -> statement
  917.                                                          : (for_statement ? for_statement -> statement
  918.                                                                           : (while_statement ? while_statement -> statement
  919.                                                                                              : (AstStatement *) NULL)));
  920.         if (enclosed_statement)
  921.             enclosed_statement -> can_complete_normally = true;
  922.         else
  923.         {
  924.             assert(continue_statement -> identifier_token_opt);
  925.  
  926.             ReportSemError(SemanticError::INVALID_CONTINUE_TARGET,
  927.                            continue_statement -> LeftToken(),
  928.                            continue_statement -> RightToken(),
  929.                            lex_stream -> NameString(continue_statement -> identifier_token_opt));
  930.         }
  931.     }
  932.  
  933.     return;
  934. }
  935.  
  936.  
  937. void Semantic::ProcessReturnStatement(Ast *stmt)
  938. {
  939.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  940.  
  941.     MethodSymbol *this_method = ThisMethod();
  942.  
  943.     if (this_method -> name_symbol == control.clinit_name_symbol || this_method -> name_symbol == control.block_init_name_symbol)
  944.     {
  945.         ReportSemError(SemanticError::RETURN_STATEMENT_IN_INITIALIZER,
  946.                        return_statement -> LeftToken(),
  947.                        return_statement -> RightToken());
  948.     }
  949.     else if (return_statement -> expression_opt)
  950.     {
  951.         ProcessExpression(return_statement -> expression_opt);
  952.  
  953.         if (this_method -> Type() == control.void_type)
  954.         {
  955.             ReportSemError(SemanticError::MISPLACED_RETURN_WITH_EXPRESSION,
  956.                            return_statement -> LeftToken(),
  957.                            return_statement -> RightToken());
  958.         }
  959.         else if (return_statement -> expression_opt -> Type() != control.no_type)
  960.         {
  961.             if (this_method -> Type() != return_statement -> expression_opt -> Type())
  962.             {
  963.                 if (CanAssignmentConvert(this_method -> Type(), return_statement -> expression_opt))
  964.                     return_statement -> expression_opt = ConvertToType(return_statement -> expression_opt, this_method -> Type());
  965.                 else
  966.                 {
  967.                     ReportSemError(SemanticError::MISMATCHED_RETURN_AND_METHOD_TYPE,
  968.                                    return_statement -> expression_opt -> LeftToken(),
  969.                                    return_statement -> expression_opt -> RightToken(),
  970.                                    return_statement -> expression_opt -> Type() -> ContainingPackage() -> PackageName(),
  971.                                    return_statement -> expression_opt -> Type() -> ExternalName(),
  972.                                    this_method -> Type() -> ContainingPackage() -> PackageName(),
  973.                                    this_method -> Type() -> ExternalName());
  974.                 }
  975.             }
  976.         }
  977.     }
  978.     else if (this_method -> Type() != control.void_type)
  979.     {
  980.         ReportSemError(SemanticError::MISPLACED_RETURN_WITH_NO_EXPRESSION,
  981.                        return_statement -> LeftToken(),
  982.                        return_statement -> RightToken());
  983.     }
  984.  
  985.     return;
  986. }
  987.  
  988.  
  989. bool Semantic::CatchableException(TypeSymbol *exception)
  990. {
  991.     //
  992.     // An unchecked exception or an error is ok !!
  993.     //
  994.     if (! CheckedException(exception) || exception == control.no_type)
  995.         return true;
  996.  
  997.     //
  998.     // Firstly, check the stack of try statements to see if the exception in question is catchable.
  999.     //
  1000.     for (int i = TryStatementStack().Size() - 1; i >= 0; i--)
  1001.     {
  1002.         AstTryStatement *try_statement = (AstTryStatement *) TryStatementStack()[i];
  1003.  
  1004.         //
  1005.         // If a try statement contains a finally clause that can complete abruptly
  1006.         // then any exception that can reach it is assumed to be catchable.
  1007.         // See Spec 11.3.
  1008.         //
  1009.         if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  1010.             return true;
  1011.  
  1012.         //
  1013.         // Check each catch clause in turn.
  1014.         //
  1015.         for (int k = 0; k < try_statement -> NumCatchClauses(); k++)
  1016.         {
  1017.             AstCatchClause *clause = try_statement -> CatchClause(k);
  1018.             VariableSymbol *symbol = clause -> parameter_symbol;
  1019.             if (CanAssignmentConvertReference(symbol -> Type(), exception))
  1020.                 return true;
  1021.         }
  1022.     }
  1023.  
  1024.     //
  1025.     // If we are processing the initialization expression of a field,
  1026.     // ThisMethod() is not defined.
  1027.     //
  1028.     MethodSymbol *this_method = ThisMethod();
  1029.     if (this_method)
  1030.     {
  1031.         for (int l = this_method -> NumThrows() - 1; l >= 0; l--)
  1032.         {
  1033.             if (CanAssignmentConvertReference(this_method -> Throws(l), exception))
  1034.                 return true;
  1035.         }
  1036.  
  1037.         if (this_method -> NumInitializerConstructors() > 0)
  1038.         {
  1039.             int j;
  1040.             for (j = this_method -> NumInitializerConstructors() - 1; j >= 0; j--)
  1041.             {
  1042.                 MethodSymbol *method = this_method -> InitializerConstructor(j);
  1043.                 int k;
  1044.                 for (k = method -> NumThrows() - 1; k >= 0; k--)
  1045.                 {
  1046.                     if (CanAssignmentConvertReference(method -> Throws(k), exception))
  1047.                         break;
  1048.                 }
  1049.                 if (k < 0) // no hit was found in method.
  1050.                     return false;
  1051.             }
  1052.             if (j < 0) // all the relevant constructors can catch the exception
  1053.                 return true;
  1054.         }
  1055.     }
  1056.  
  1057.     return false;
  1058. }
  1059.  
  1060.  
  1061. void Semantic::ProcessThrowStatement(Ast *stmt)
  1062. {
  1063.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1064.  
  1065.     ProcessExpression(throw_statement -> expression);
  1066.     TypeSymbol *type = throw_statement -> expression -> Type();
  1067.  
  1068.     if (type != control.no_type && (! CanAssignmentConvertReference(control.Throwable(), type)))
  1069.     {
  1070.         ReportSemError(SemanticError::EXPRESSION_NOT_THROWABLE,
  1071.                        throw_statement -> LeftToken(),
  1072.                        throw_statement -> RightToken());
  1073.     }
  1074.  
  1075.     SymbolSet *exception_set = TryExceptionTableStack().Top();
  1076.     if (exception_set)
  1077.         exception_set -> AddElement(type);
  1078.  
  1079.     if (! CatchableException(type))
  1080.     {
  1081.         MethodSymbol *this_method = ThisMethod();
  1082.         MethodSymbol *method = (this_method && this_method -> Identity() != control.clinit_name_symbol
  1083.                                             && this_method -> Identity() != control.block_init_name_symbol
  1084.                                                             ? this_method
  1085.                                                             : (MethodSymbol *) NULL);
  1086.  
  1087.         if (TryStatementStack().Size() > 0)
  1088.             ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_TRY,
  1089.                            throw_statement -> LeftToken(),
  1090.                            throw_statement -> RightToken(),
  1091.                            type -> ContainingPackage() -> PackageName(),
  1092.                            type -> ExternalName(),
  1093.                            (method ? method -> Header() : StringConstant::US_EMPTY));
  1094.         else if (method)
  1095.              ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_METHOD,
  1096.                             throw_statement -> LeftToken(),
  1097.                             throw_statement -> RightToken(),
  1098.                             type -> ContainingPackage() -> PackageName(),
  1099.                             type -> ExternalName(),
  1100.                             method -> Header());
  1101.         else ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION,
  1102.                             throw_statement -> LeftToken(),
  1103.                             throw_statement -> RightToken(),
  1104.                             type -> ContainingPackage() -> PackageName(),
  1105.                             type -> ExternalName());
  1106.     }
  1107.  
  1108.     return;
  1109. }
  1110.  
  1111.  
  1112. void Semantic::ProcessTryStatement(Ast *stmt)
  1113. {
  1114.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1115.  
  1116.     //
  1117.     // A try_statement containing a finally clause requires some extra local
  1118.     // variables in its immediately enclosing block. If it is enclosed in a method
  1119.     // that returns void then 2 extra elements are needed. If the method
  1120.     // returns a long or a double value, two additional elements are needed.
  1121.     // Otherwise, one additional element is needed.
  1122.     // If this try_statement is the first try_statement with a finally clause
  1123.     // that was encountered in the immediately enclosing block, we allocate
  1124.     // two extra slots for the special local variables.
  1125.     //
  1126.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  1127.     if (try_statement -> finally_clause_opt)
  1128.     {
  1129.         BlockSymbol *enclosing_block_symbol = enclosing_block -> block_symbol;
  1130.         if (enclosing_block_symbol -> try_or_synchronized_variable_index == 0) // first such statement encountered in enclosing block?
  1131.         {
  1132.             enclosing_block_symbol -> try_or_synchronized_variable_index = enclosing_block_symbol -> max_variable_index;
  1133.             enclosing_block_symbol -> max_variable_index += 2;
  1134.             if (ThisMethod() -> Type() != control.void_type)
  1135.             {
  1136.                  if (control.IsDoubleWordType(ThisMethod() -> Type()))
  1137.                       enclosing_block_symbol -> max_variable_index += 2;
  1138.                  else enclosing_block_symbol -> max_variable_index += 1;
  1139.             }
  1140.         }
  1141.  
  1142.         //
  1143.         // A finally block is processed in the environment of its immediate enclosing block.
  1144.         // (as opposed to the environment of its associated try block).
  1145.         //
  1146.         // Note that the finally block must be processed prior to the other
  1147.         // blocks in the try statement, because the computation of whether or not
  1148.         // an exception is catchable in a try statement depends on the termination
  1149.         // status of the associated finally block. See CatchableException function.
  1150.         //
  1151.         AstBlock *block_body = try_statement -> finally_clause_opt -> block;
  1152.         block_body -> is_reachable = try_statement -> is_reachable;
  1153.         ProcessBlock(block_body);
  1154.     }
  1155.  
  1156.     //
  1157.     // Note that the catch clauses are processed first - prior to processing
  1158.     // the main block - so that we can have their parameters available when we
  1159.     // are processing the main block, in case that block contains a throw
  1160.     // statement. See ProcessThrowStatement for more information.
  1161.     //
  1162.     // Also, recall that the body of the catch blocks must not be
  1163.     // processed within the environment of the associated try whose
  1164.     // exceptions they are supposed to catch but within the immediate enclosing
  1165.     // block (which may itself be a try block).
  1166.     //
  1167.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1168.     {
  1169.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1170.         AstFormalParameter *parameter = clause -> formal_parameter;
  1171.  
  1172.         TypeSymbol *parm_type;
  1173.  
  1174.         if (parameter -> type -> PrimitiveTypeCast())
  1175.         {
  1176.             ReportSemError(SemanticError::CATCH_PRIMITIVE_TYPE,
  1177.                            parameter -> LeftToken(),
  1178.                            parameter -> RightToken());
  1179.             parm_type = control.Error();
  1180.         }
  1181.         else if (parameter -> type -> ArrayTypeCast())
  1182.         {
  1183.             ReportSemError(SemanticError::CATCH_ARRAY_TYPE,
  1184.                            parameter -> LeftToken(),
  1185.                            parameter -> RightToken());
  1186.             parm_type = control.Error();
  1187.         }
  1188.         else parm_type = MustFindType(parameter -> type);
  1189.  
  1190.         if (! parm_type -> IsSubclass(control.Throwable()))
  1191.         {
  1192.             ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1193.                            parameter -> LeftToken(),
  1194.                            parameter -> RightToken(),
  1195.                            parm_type -> ContainingPackage() -> PackageName(),
  1196.                            parm_type -> ExternalName());
  1197.         }
  1198.  
  1199.         AstVariableDeclaratorId *name = parameter -> formal_declarator -> variable_declarator_name;
  1200.         NameSymbol *name_symbol = lex_stream -> NameSymbol(name -> identifier_token);
  1201.         if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  1202.         {
  1203.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  1204.                            name -> identifier_token,
  1205.                            name -> identifier_token,
  1206.                            name_symbol -> Name());
  1207.         }
  1208.  
  1209.         AstBlock *block_body = clause -> block;
  1210.         //
  1211.         // Guess that the number of elements in the table will not exceed the number of statements + the clause parameter.
  1212.         //
  1213.         BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 1);
  1214.         block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  1215.         LocalSymbolTable().Push(block -> Table());
  1216.  
  1217.         AccessFlags access_flags = ProcessFormalModifiers(parameter);
  1218.  
  1219.         VariableSymbol *symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  1220.         symbol -> SetFlags(access_flags);
  1221.         symbol -> SetType(parm_type);
  1222.         symbol -> SetOwner(ThisMethod());
  1223.         symbol -> SetLocalVariableIndex(block -> max_variable_index++);
  1224.         symbol -> declarator = parameter -> formal_declarator;
  1225.  
  1226.         clause -> parameter_symbol = symbol;
  1227.  
  1228.         //
  1229.         // Note that for the purpose of semantic checking we assume that
  1230.         // the body of the catch block is reachable. Whether or not the catch
  1231.         // statement can be executed at all is checked later.
  1232.         //
  1233.         block_body -> is_reachable = true;
  1234.  
  1235.         block_body -> block_symbol = block;
  1236.         block_body -> nesting_level = LocalBlockStack().Size();
  1237.         LocalBlockStack().Push(block_body);
  1238.  
  1239.         ProcessBlockStatements(block_body);
  1240.  
  1241.         LocalBlockStack().Pop();
  1242.         LocalSymbolTable().Pop();
  1243.  
  1244.         //
  1245.         // Update the information for the block that immediately encloses the current block.
  1246.         //
  1247.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  1248.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  1249.  
  1250.         //
  1251.         // If a catch clause block can complete normally, we assume
  1252.         // that the try statement can complete normally. This may
  1253.         // prove to be false later if we find out that the finally
  1254.         // clause cannot complete normally...
  1255.         //
  1256.         if (block_body -> can_complete_normally)
  1257.             try_statement -> can_complete_normally = true;
  1258.  
  1259.         block -> CompressSpace(); // space optimization
  1260.     }
  1261.  
  1262.     //
  1263.     //
  1264.     //
  1265.     TryStatementStack().Push(try_statement);
  1266.     SymbolSet *exception_set = new SymbolSet;
  1267.     TryExceptionTableStack().Push(exception_set);
  1268.  
  1269.     try_statement -> block -> is_reachable = try_statement -> is_reachable;
  1270.     ProcessBlock(try_statement -> block);
  1271.     if (try_statement -> block -> can_complete_normally)
  1272.         try_statement -> can_complete_normally = true;
  1273.  
  1274.     //
  1275.     // A catch block is reachable iff both of the following are true:
  1276.     //
  1277.     //     . Some expression or throw statement in the try block is reachable
  1278.     //       and can throw an exception that is assignable to the parameter
  1279.     //       of the catch clause C.
  1280.     //
  1281.     //     . There is no earlier catch block A in the try statement such that the
  1282.     //       type of C's parameter is the same as or a subclass of the type of A's
  1283.     //       parameter.
  1284.     //
  1285.     // Note that the use of the word assignable here is slightly misleading.
  1286.     // It does not mean assignable in the strict sense defined in section 5.2.
  1287.     // Using the strict definition of 5.2, the rule can be more accurately 
  1288.     // stated as follows:
  1289.     //
  1290.     //    . Catchable Exception:
  1291.     //      some expression or throw statement in the try block is reachable
  1292.     //      and can throw an exception S that is assignable to the parameter
  1293.     //      with type T (S is a subclass of T) of the catch clause C.
  1294.     //
  1295.     //      In this case, when S is thrown it will definitely be caught by
  1296.     //      clause C.
  1297.     //
  1298.     //    . Convertible Exception:
  1299.     //      the type T of the parameter of the catch clause C is assignable to
  1300.     //      the type S (T is a subclass of S) of an exception that can be thrown by
  1301.     //      some expression or throw statement in the try block that is reachable.
  1302.     //      
  1303.     //      This rule captures the idea that at run time an object declared to
  1304.     //      be of type S can actually be an instance of an object of type T in
  1305.     //      which case it will be caught by clause C.
  1306.     //
  1307.     //
  1308.     Tuple<TypeSymbol *> catchable_exceptions,
  1309.                         convertible_exceptions;
  1310.     for (int l = 0; l < try_statement -> NumCatchClauses(); l++)
  1311.     {
  1312.         AstCatchClause *clause = try_statement -> CatchClause(l);
  1313.         VariableSymbol *symbol = clause -> parameter_symbol;
  1314.         if (CheckedException(symbol -> Type()))
  1315.         {
  1316.             int initial_length = catchable_exceptions.Length() + convertible_exceptions.Length();
  1317.  
  1318.             for (TypeSymbol *exception = (TypeSymbol *) exception_set -> FirstElement();
  1319.                  exception;
  1320.                  exception = (TypeSymbol *) exception_set -> NextElement())
  1321.             {
  1322.                 if (CanAssignmentConvertReference(symbol -> Type(), exception))
  1323.                      catchable_exceptions.Next() = exception;
  1324.                 else if (CanAssignmentConvertReference(exception, symbol -> Type()))
  1325.                      convertible_exceptions.Next() = exception;
  1326.             }
  1327.  
  1328.             //
  1329.             // No clause was found whose parameter can possibly accept this exception.
  1330.             //
  1331.             if ((catchable_exceptions.Length() + convertible_exceptions.Length()) == initial_length)
  1332.             {
  1333.                 if (symbol -> Type() == control.Throwable() || symbol -> Type() == control.Exception())
  1334.                      ReportSemError(SemanticError::UNREACHABLE_DEFAULT_CATCH_CLAUSE,
  1335.                                     clause -> formal_parameter -> LeftToken(),
  1336.                                     clause -> formal_parameter -> RightToken(),
  1337.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1338.                                     symbol -> Type() -> ExternalName());
  1339.                 else ReportSemError(SemanticError::UNREACHABLE_CATCH_CLAUSE,
  1340.                                     clause -> formal_parameter -> LeftToken(),
  1341.                                     clause -> formal_parameter -> RightToken(),
  1342.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1343.                                     symbol -> Type() -> ExternalName());
  1344.             }
  1345.             else
  1346.             {
  1347.                 //
  1348.                 // TODO: I know, I know, this is a sequential search...
  1349.                 //
  1350.                 AstCatchClause *previous_clause;
  1351.                 int k;
  1352.                 for (k = 0; k < l; k++)
  1353.                 {
  1354.                     previous_clause = try_statement -> CatchClause(k);
  1355.                     if (symbol -> Type() -> IsSubclass(previous_clause -> parameter_symbol -> Type()))
  1356.                         break;
  1357.                 }
  1358.  
  1359.                 if (k < l)
  1360.                 {
  1361.                      FileLocation loc(lex_stream, previous_clause -> formal_parameter -> RightToken());
  1362.                      ReportSemError(SemanticError::BLOCKED_CATCH_CLAUSE,
  1363.                                     clause -> formal_parameter -> LeftToken(),
  1364.                                     clause -> formal_parameter -> RightToken(),
  1365.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1366.                                     symbol -> Type() -> ExternalName(),
  1367.                                     loc.location);
  1368.                 }
  1369.                 else clause -> block -> is_reachable = true;
  1370.             }
  1371.         }
  1372.     }
  1373.  
  1374.     TryStatementStack().Pop();
  1375.     TryExceptionTableStack().Pop();
  1376.     if (TryExceptionTableStack().Top())
  1377.     {
  1378.         //
  1379.         // First, remove all the thrown exceptions that are definitely caught by the
  1380.         // enclosing try statement. Then, add the remaining ones to the set that must
  1381.         // be caught by the immediately enclosing try statement.
  1382.         //
  1383.         for (int i = 0; i < catchable_exceptions.Length(); i++)
  1384.             exception_set -> RemoveElement(catchable_exceptions[i]);
  1385.         TryExceptionTableStack().Top() -> Union(*exception_set);
  1386.     }
  1387.     delete exception_set;
  1388.  
  1389.     //
  1390.     // A try statement cannot complete normally if it contains a finally
  1391.     // clause that cannot complete normally.
  1392.     //
  1393.     if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  1394.         try_statement -> can_complete_normally = false;
  1395.  
  1396.     return;
  1397. }
  1398.  
  1399.  
  1400. void Semantic::ProcessEmptyStatement(Ast *stmt)
  1401. {
  1402.     AstEmptyStatement *empty_statement = (AstEmptyStatement *) stmt;
  1403.  
  1404.     //
  1405.     // An empty statement can complete normally iff it is reachable.
  1406.     //
  1407.     empty_statement -> can_complete_normally = empty_statement -> is_reachable;
  1408.  
  1409.     return;
  1410. }
  1411.  
  1412.  
  1413. TypeSymbol *Semantic::GetLocalType(AstClassDeclaration *class_declaration)
  1414. {
  1415.     NameSymbol *name_symbol = lex_stream -> NameSymbol(class_declaration -> identifier_token);
  1416.     TypeSymbol *type = LocalSymbolTable().Top() -> InsertNestedTypeSymbol(name_symbol);
  1417.  
  1418.     TypeSymbol *outermost_type = ThisType() -> outermost_type;
  1419.     if (! outermost_type -> local)
  1420.         outermost_type -> local = new SymbolSet;
  1421.  
  1422.     IntToWstring value(outermost_type -> local -> NameCount(name_symbol) + 1);
  1423.  
  1424.     int length = value.Length() + outermost_type -> NameLength() + 1 + name_symbol -> NameLength() + 1; // +1 for $,... +1 for $
  1425.     wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  1426.     wcscpy(external_name, outermost_type -> Name());
  1427.     wcscat(external_name, StringConstant::US__DS);
  1428.     wcscat(external_name, value.String());
  1429.     wcscat(external_name, StringConstant::US__DS);
  1430.     wcscat(external_name, name_symbol -> Name());
  1431.  
  1432.     type -> SetACC_PRIVATE();
  1433.     type -> outermost_type = outermost_type;
  1434.     type -> SetExternalIdentity(control.FindOrInsertName(external_name, length));
  1435.     outermost_type -> local -> AddElement(type);
  1436.  
  1437.     delete [] external_name;
  1438.  
  1439.     return type;
  1440. }
  1441.  
  1442.  
  1443. void Semantic::ProcessClassDeclaration(Ast *stmt)
  1444. {
  1445.     AstClassDeclaration *class_declaration = (AstClassDeclaration *) stmt;
  1446.     AstClassBody *class_body = class_declaration -> class_body;
  1447.  
  1448.     class_declaration -> MarkLocal(); // identify class as "statement" and assert that it is "reachable" and "can_complete_normally"
  1449.     CheckNestedTypeDuplication(state_stack.Top(), class_declaration -> identifier_token);
  1450.  
  1451.     TypeSymbol *inner_type = GetLocalType(class_declaration);
  1452.     inner_type -> outermost_type = ThisType() -> outermost_type;
  1453.     inner_type -> supertypes_closure = new SymbolSet;
  1454.     inner_type -> subtypes_closure = new SymbolSet;
  1455.     inner_type -> subtypes = new SymbolSet;
  1456.     inner_type -> semantic_environment = new SemanticEnvironment((Semantic *) this,
  1457.                                                                  inner_type,
  1458.                                                                  state_stack.Top());
  1459.     inner_type -> declaration = class_declaration;
  1460.     inner_type -> file_symbol = source_file_symbol;
  1461.     inner_type -> SetFlags(ProcessLocalClassModifiers(class_declaration));
  1462.     inner_type -> SetOwner(ThisMethod());
  1463.     //
  1464.     // Add 3 extra elements for padding. May need a default constructor and other support elements.
  1465.     //
  1466.     inner_type -> SetSymbolTable(class_body -> NumClassBodyDeclarations() + 3);
  1467.     inner_type -> SetLocation();
  1468.     inner_type -> SetSignature(control);
  1469.  
  1470.     if (StaticRegion())
  1471.          inner_type -> SetACC_STATIC();
  1472.     else inner_type -> InsertThis(0);
  1473.  
  1474.     class_declaration -> semantic_environment = inner_type -> semantic_environment; // save for processing bodies later.
  1475.  
  1476.     CheckClassMembers(inner_type, class_body);
  1477.  
  1478.     ProcessTypeHeaders(class_declaration);
  1479.  
  1480.     ProcessMembers(class_declaration -> semantic_environment, class_body);
  1481.     CompleteSymbolTable(class_declaration -> semantic_environment, class_declaration -> identifier_token, class_body);
  1482.     ProcessExecutableBodies(class_declaration -> semantic_environment, class_body);
  1483.  
  1484.     UpdateLocalConstructors(inner_type);
  1485.  
  1486.     return;
  1487. }
  1488.  
  1489.  
  1490. void Semantic::ProcessThisCall(AstThisCall *this_call)
  1491. {
  1492.     TypeSymbol *this_type = ThisType(),
  1493.                *containing_type = this_type -> ContainingType();
  1494.  
  1495.     ExplicitConstructorInvocation() = this_call; // signal that we are about to process an explicit constructor invocation
  1496.  
  1497.     if (this_call -> base_opt)
  1498.     {
  1499.         ProcessExpression(this_call -> base_opt);
  1500.  
  1501.         TypeSymbol *expr_type = this_call -> base_opt -> Type();
  1502.         if (expr_type != control.no_type)
  1503.         {
  1504.             if (! containing_type)
  1505.             {
  1506.                 ReportSemError(SemanticError::TYPE_NOT_INNER_CLASS,
  1507.                                this_call -> base_opt -> LeftToken(),
  1508.                                this_call -> base_opt -> RightToken(),
  1509.                                this_type -> ContainingPackage() -> PackageName(),
  1510.                                this_type -> ExternalName(),
  1511.                                expr_type -> ContainingPackage() -> PackageName(),
  1512.                                expr_type -> ExternalName());
  1513.                 this_call -> base_opt -> symbol = control.no_type;
  1514.             }
  1515.             //
  1516.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1517.             // be a perfect match.
  1518.             //
  1519.             // else if (! expr_type -> IsSubclass(containing_type))
  1520.             //
  1521.             else if (expr_type != containing_type)
  1522.             {
  1523.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1524.                                this_call -> base_opt -> LeftToken(),
  1525.                                this_call -> base_opt -> RightToken(),
  1526.                                this_type -> ContainingPackage() -> PackageName(),
  1527.                                this_type -> ExternalName(),
  1528.                                containing_type -> ContainingPackage() -> PackageName(),
  1529.                                containing_type -> ExternalName(),
  1530.                                expr_type -> ContainingPackage() -> PackageName(),
  1531.                                expr_type -> ExternalName());
  1532.                 this_call -> base_opt -> symbol = control.no_type;
  1533.             }
  1534.         }
  1535.     }
  1536.     else // (! this_call -> base_opt)
  1537.     {
  1538.         if (this_type -> IsInner())
  1539.             this_call -> base_opt = CreateAccessToType(this_call, containing_type);
  1540.     }
  1541.  
  1542.     bool no_bad_argument = true;
  1543.  
  1544.     for (int i = 0; i < this_call -> NumArguments(); i++)
  1545.     {
  1546.         AstExpression *expr = (AstExpression *) this_call -> Argument(i);
  1547.         ProcessExpressionOrStringConstant(expr);
  1548.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1549.     }
  1550.     if (no_bad_argument)
  1551.     {
  1552.         MethodSymbol *constructor = FindConstructor(this_type, this_call, this_call -> this_token, this_call -> RightToken());
  1553.         if (constructor)
  1554.         {
  1555.             this_call -> symbol = constructor;
  1556.  
  1557.             for (int i = 0; i < this_call -> NumArguments(); i++)
  1558.             {
  1559.                 AstExpression *expr = this_call -> Argument(i);
  1560.                 if (expr -> Type() != constructor -> FormalParameter(i) -> Type())
  1561.                     this_call -> Argument(i) = ConvertToType(expr, constructor -> FormalParameter(i) -> Type());
  1562.             }
  1563.  
  1564.             for (int k = constructor -> NumThrows() - 1; k >= 0; k--)
  1565.             {
  1566.                 TypeSymbol *exception = constructor -> Throws(k);
  1567.                 if (! CatchableException(exception))
  1568.                 {
  1569.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_THIS_EXCEPTION,
  1570.                                    this_call -> this_token,
  1571.                                    this_call -> this_token,
  1572.                                    exception -> ContainingPackage() -> PackageName(),
  1573.                                    exception -> ExternalName());
  1574.                 }
  1575.             }
  1576.  
  1577.             if (this_type -> IsLocal()) // a local type may use enclosed local variables?
  1578.                 this_type -> AddLocalConstructorCallEnvironment(GetEnvironment(this_call));
  1579.  
  1580.             //
  1581.             // Note that there is no need to do access-checking as we are allowed,
  1582.             // within the body of a class, to invoke any other constructor or member
  1583.             // (private or otherwise) in that class.
  1584.             //
  1585.         }
  1586.     }
  1587.  
  1588.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1589.  
  1590.     this_call -> can_complete_normally = this_call -> is_reachable;
  1591.  
  1592.     return;
  1593. }
  1594.  
  1595.  
  1596. void Semantic::ProcessSuperCall(AstSuperCall *super_call)
  1597. {
  1598.     TypeSymbol *this_type = ThisType();
  1599.     ExplicitConstructorInvocation() = super_call; // signal that we are about to process an explicit constructor invocation
  1600.  
  1601.     TypeSymbol *super_type = this_type -> super;
  1602.     if (! super_type) // this is only possible if we are compiling an illegal Object.java source file.
  1603.         super_type = control.Object();
  1604.  
  1605.     if (super_call -> base_opt)
  1606.     {
  1607.         ProcessExpression(super_call -> base_opt);
  1608.  
  1609.         TypeSymbol *expr_type = super_call -> base_opt -> Type();
  1610.         if (expr_type != control.no_type)
  1611.         {
  1612.             TypeSymbol *containing_type = super_type -> ContainingType();
  1613.             if (! containing_type)
  1614.             {
  1615.                 ReportSemError(SemanticError::SUPER_TYPE_NOT_INNER_CLASS,
  1616.                                super_call -> base_opt -> LeftToken(),
  1617.                                super_call -> base_opt -> RightToken(),
  1618.                                super_type -> ContainingPackage() -> PackageName(),
  1619.                                super_type -> ExternalName(),
  1620.                                this_type -> ContainingPackage() -> PackageName(),
  1621.                                this_type -> ExternalName(),
  1622.                                expr_type -> ContainingPackage() -> PackageName(),
  1623.                                expr_type -> ExternalName());
  1624.                 super_call -> base_opt -> symbol = control.no_type;
  1625.             }
  1626.             //
  1627.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1628.             // be a perfect match.
  1629.             //
  1630.             // else if (! expr_type -> IsSubclass(containing_type))
  1631.             //
  1632.             else if (expr_type != containing_type)
  1633.             {
  1634.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1635.                                super_call -> base_opt -> LeftToken(),
  1636.                                super_call -> base_opt -> RightToken(),
  1637.                                this_type -> ContainingPackage() -> PackageName(),
  1638.                                this_type -> ExternalName(),
  1639.                                containing_type -> ContainingPackage() -> PackageName(),
  1640.                                containing_type -> ExternalName(),
  1641.                                expr_type -> ContainingPackage() -> PackageName(),
  1642.                                expr_type -> ExternalName());
  1643.                 super_call -> base_opt -> symbol = control.no_type;
  1644.             }
  1645.         }
  1646.     }
  1647.     else // (! super_call -> base_opt)
  1648.     {
  1649.         if (super_type && super_type -> IsInner())
  1650.             super_call -> base_opt = CreateAccessToType(super_call, super_type -> ContainingType());
  1651.     }
  1652.  
  1653.     bool no_bad_argument = true;
  1654.     for (int i = 0; i < super_call -> NumArguments(); i++)
  1655.     {
  1656.         AstExpression *expr = (AstExpression *) super_call -> Argument(i);
  1657.         ProcessExpressionOrStringConstant(expr);
  1658.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1659.     }
  1660.  
  1661.     if (this_type == control.Object())
  1662.     {
  1663.         super_call -> symbol = NULL;
  1664.         ReportSemError(SemanticError::MISPLACED_SUPER_EXPRESSION,
  1665.                        super_call -> super_token,
  1666.                        super_call -> super_token);
  1667.     }
  1668.     else if (no_bad_argument)
  1669.     {
  1670.         MethodSymbol *constructor = FindConstructor(super_type, super_call, super_call -> super_token, super_call -> RightToken());
  1671.  
  1672.         if (constructor)
  1673.         {
  1674.             //
  1675.             // No need to do a full access-check. Do the minimal stuff here !
  1676.             //
  1677.             if (constructor -> ACC_PRIVATE())
  1678.             {
  1679.                 if (this_type -> outermost_type == super_type -> outermost_type)
  1680.                 {
  1681.                      if (! constructor -> LocalConstructor())
  1682.                      {
  1683.                          constructor = super_type -> GetReadAccessMethod(constructor);
  1684.  
  1685.                          //
  1686.                          // Add extra argument for read access constructor;
  1687.                          //
  1688.                          super_call -> AddNullArgument();
  1689.                      }
  1690.                 }
  1691.                 else ReportSemError(SemanticError::PRIVATE_CONSTRUCTOR_NOT_ACCESSIBLE,
  1692.                                     super_call -> LeftToken(),
  1693.                                     super_call -> RightToken(),
  1694.                                     constructor -> Header(),
  1695.                                     super_type -> ContainingPackage() -> PackageName(),
  1696.                                     super_type -> ExternalName());
  1697.             }
  1698.             else if (! (constructor -> ACC_PUBLIC() || constructor -> ACC_PROTECTED()))
  1699.             {
  1700.                 if (! (this_type -> outermost_type == super_type -> outermost_type ||
  1701.                        super_type -> ContainingPackage() == this_package))
  1702.                     ReportSemError(SemanticError::DEFAULT_CONSTRUCTOR_NOT_ACCESSIBLE,
  1703.                                    super_call -> super_token,
  1704.                                    super_call -> super_token,
  1705.                                    constructor -> Header(),
  1706.                                    super_type -> ContainingPackage() -> PackageName(),
  1707.                                    super_type -> ExternalName());
  1708.             }
  1709.  
  1710.             super_call -> symbol = constructor;
  1711.  
  1712.             if (super_call -> base_opt &&
  1713.                 (super_call -> base_opt -> Type() != control.no_type) &&
  1714.                 (super_call -> base_opt -> Type() != super_type -> ContainingType()))
  1715.             {
  1716.                 assert(CanMethodInvocationConvert(super_type -> ContainingType(), super_call -> base_opt -> Type()));
  1717.  
  1718.                 super_call -> base_opt = ConvertToType(super_call -> base_opt, super_type -> ContainingType());
  1719.             }
  1720.  
  1721.             for (int i = 0; i < super_call -> NumArguments(); i++)
  1722.             {
  1723.                 AstExpression *expr = super_call -> Argument(i);
  1724.                 if (expr -> Type() != constructor -> FormalParameter(i) -> Type())
  1725.                     super_call -> Argument(i) = ConvertToType(expr, constructor -> FormalParameter(i) -> Type());
  1726.             }
  1727.  
  1728.             //
  1729.             // Make sure that the throws signature of the constructor is processed.
  1730.             //
  1731.             for (int k = constructor -> NumThrows() - 1; k >= 0; k--)
  1732.             {
  1733.                 TypeSymbol *exception = constructor -> Throws(k);
  1734.                 if (! CatchableException(exception))
  1735.                 {
  1736.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_SUPER_EXCEPTION,
  1737.                                    super_call -> LeftToken(),
  1738.                                    super_call -> RightToken(),
  1739.                                    this_type -> Name(),
  1740.                                    exception -> ContainingPackage() -> PackageName(),
  1741.                                    exception -> ExternalName(),
  1742.                                    constructor -> containing_type -> ContainingPackage() -> PackageName(),
  1743.                                    constructor -> containing_type -> ExternalName());
  1744.                 }
  1745.             }
  1746.  
  1747.             if (super_type -> IsLocal()) // a local type may use enclosed local variables?
  1748.             {
  1749.                 if (super_type -> LocalClassProcessingCompleted())
  1750.                 {
  1751.                     assert(ThisMethod() -> LocalConstructor() && (! ThisMethod() -> IsGeneratedLocalConstructor()));
  1752.  
  1753.                     assert(constructor -> LocalConstructor() && (! constructor -> IsGeneratedLocalConstructor()));
  1754.  
  1755.                     super_call -> symbol = constructor -> LocalConstructor();
  1756.  
  1757.                     //
  1758.                     // Recall that as a side-effect, when a local shadow is created in a type
  1759.                     // an argument that will be used to initialize the local shadow that has
  1760.                     // the same identity must be passed to every constructor in the type. Since
  1761.                     // we are currently processing a constructor, such an argument must be available.
  1762.                     //
  1763.                     BlockSymbol *block_symbol = ThisMethod() -> LocalConstructor() -> block_symbol;
  1764.                     for (int i = (super_type -> ACC_STATIC() ? 0 : 1); i < super_type -> NumConstructorParameters(); i++)
  1765.                     {
  1766.                         VariableSymbol *local = super_type -> ConstructorParameter(i) -> accessed_local,
  1767.                                        *local_shadow = this_type -> FindOrInsertLocalShadow(local);
  1768.  
  1769.                         AstSimpleName *simple_name = compilation_unit -> ast_pool -> GenSimpleName(super_call -> super_token);
  1770.                         simple_name -> symbol = block_symbol -> FindVariableSymbol(local_shadow -> Identity());
  1771.  
  1772.                         assert(simple_name -> symbol);
  1773.  
  1774.                         super_call -> AddLocalArgument(simple_name);
  1775.                     }
  1776.                 }
  1777.                 else // are we currently within the body of the type in question ?
  1778.                 {
  1779.                     super_type -> AddLocalConstructorCallEnvironment(GetEnvironment(super_call));
  1780.                 }
  1781.             }
  1782.         }
  1783.     }
  1784.  
  1785.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1786.  
  1787.     super_call -> can_complete_normally = super_call -> is_reachable;
  1788.  
  1789.     return;
  1790. }
  1791.  
  1792.  
  1793. void Semantic::CheckThrow(AstExpression *throw_expression)
  1794. {
  1795.     TypeSymbol *throw_type = throw_expression -> symbol -> TypeCast();
  1796.  
  1797.     assert(throw_type);
  1798.  
  1799.     if (throw_type -> ACC_INTERFACE())
  1800.     {
  1801.         ReportSemError(SemanticError::NOT_A_CLASS,
  1802.                        throw_expression -> LeftToken(),
  1803.                        throw_expression -> RightToken(),
  1804.                        throw_type -> ContainingPackage() -> PackageName(),
  1805.                        throw_type -> ExternalName());
  1806.     }
  1807.     else if (! throw_type -> IsSubclass(control.Throwable()))
  1808.     {
  1809.         ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1810.                        throw_expression -> LeftToken(),
  1811.                        throw_expression -> RightToken(),
  1812.                        throw_type -> ContainingPackage() -> PackageName(),
  1813.                        throw_type -> ExternalName());
  1814.     }
  1815.  
  1816.     return;
  1817. }
  1818.  
  1819.  
  1820. void Semantic::ProcessMethodBody(AstMethodDeclaration *method_declaration)
  1821. {
  1822.     MethodSymbol *this_method = ThisMethod();
  1823.  
  1824.     for (int k = 0; k < method_declaration -> NumThrows(); k++)
  1825.         CheckThrow(method_declaration -> Throw(k));
  1826.  
  1827.  
  1828.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1829.     {
  1830.         //
  1831.         // The block that is the body of a method is reachable
  1832.         //
  1833.         AstBlock *block_body;
  1834.  
  1835.         //
  1836.         // The body of a method must be a regular block. If instead, it
  1837.         // is a constructor block, mark the compilation unit as a bad
  1838.         // compilation so that the parser can properly diagnose this
  1839.         // problem later.
  1840.         //
  1841.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1842.         if (constructor_block)
  1843.         {
  1844.             compilation_unit -> kind = Ast::BAD_COMPILATION; // invalidate the compilation unit
  1845.  
  1846.             constructor_block -> is_reachable = true;
  1847.             block_body = constructor_block -> block;
  1848.  
  1849.             //
  1850.             // If the parser recognizes the body of a method as a ConstructorBlock
  1851.             // then it must have an explicit_constructor_invocation.
  1852.             //
  1853.             AstThisCall *this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1854.             if (this_call)
  1855.             {
  1856.                 this_call -> is_reachable = true;
  1857.                 //
  1858.                 // Do not process the explicit constructor invocation as this could
  1859.                 // cause problems with assertions (e.g. for inner classes) that will
  1860.                 // turn out not to be true.
  1861.                 //
  1862.                 // ProcessThisCall(this_call);
  1863.                 //
  1864.                 block_body -> is_reachable = this_call -> can_complete_normally;
  1865.             }
  1866.             else
  1867.             {
  1868.                 AstSuperCall *super_call = (AstSuperCall *) constructor_block -> explicit_constructor_invocation_opt;
  1869.                 super_call -> is_reachable = true;
  1870.                 //
  1871.                 // Do not process the explicit constructor invocation as this could
  1872.                 // cause problems with assertions (e.g. for inner classes) that will
  1873.                 // turn out not to be true.
  1874.                 //
  1875.                 // ProcessSuperCall(super_call);
  1876.                 //
  1877.                 block_body -> is_reachable = super_call -> can_complete_normally;
  1878.             }
  1879.         }
  1880.         else
  1881.         {
  1882.             block_body = (AstBlock *) method_declaration -> method_body;
  1883.             block_body -> is_reachable = true;
  1884.         }
  1885.  
  1886.         block_body -> block_symbol = this_method -> block_symbol;
  1887.         block_body -> nesting_level = LocalBlockStack().Size();
  1888.         LocalBlockStack().Push(block_body);
  1889.  
  1890.         ProcessBlockStatements(block_body);
  1891.  
  1892.         LocalBlockStack().Pop();
  1893.  
  1894.         if (block_body -> can_complete_normally)
  1895.         {
  1896.             if (this_method -> Type() == control.void_type)
  1897.             {
  1898.                 AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  1899.                 return_statement -> return_token = block_body -> right_brace_token;
  1900.                 return_statement -> expression_opt = NULL;
  1901.                 return_statement -> semicolon_token = block_body -> right_brace_token;
  1902.                 return_statement -> is_reachable = true;
  1903.                 block_body -> can_complete_normally = false;
  1904.                 block_body -> AddStatement(return_statement);
  1905.             }
  1906.             else
  1907.             {
  1908.                 ReportSemError(SemanticError::TYPED_METHOD_WITH_NO_RETURN,
  1909.                                method_declaration -> type -> LeftToken(),
  1910.                                method_declaration -> method_declarator -> identifier_token,
  1911.                                this_method -> Header(),
  1912.                                this_method -> Type() -> Name());
  1913.             }
  1914.         }
  1915.  
  1916.         if (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE())
  1917.         {
  1918.             ReportSemError(SemanticError::ABSTRACT_METHOD_WITH_BODY,
  1919.                            method_declaration -> LeftToken(),
  1920.                            method_declaration -> RightToken(),
  1921.                            this_method -> Header());
  1922.         }
  1923.     }
  1924.     else if (! (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE()))
  1925.     {
  1926.         ReportSemError(SemanticError::NON_ABSTRACT_METHOD_WITHOUT_BODY,
  1927.                        method_declaration -> LeftToken(),
  1928.                        method_declaration -> RightToken(),
  1929.                        this_method -> Header());
  1930.     }
  1931.  
  1932.     this_method -> block_symbol -> CompressSpace(); // space optimization
  1933.  
  1934.     return;
  1935. }
  1936.  
  1937.  
  1938. void Semantic::ProcessConstructorBody(AstConstructorDeclaration *constructor_declaration, bool body_reachable)
  1939. {
  1940.     TypeSymbol *this_type = ThisType();
  1941.     MethodSymbol *this_method = ThisMethod();
  1942.  
  1943.     for (int k = 0; k < constructor_declaration -> NumThrows(); k++)
  1944.         CheckThrow(constructor_declaration -> Throw(k));
  1945.  
  1946.     //
  1947.     // The block that is the body of a constructor is reachable
  1948.     //
  1949.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  1950.  
  1951.     constructor_block -> is_reachable = true;
  1952.     AstBlock *block_body = constructor_block -> block;
  1953.     AstThisCall *this_call = NULL;
  1954.     AstSuperCall *super_call = NULL;
  1955.     TypeSymbol *super_type = this_type -> super;
  1956.  
  1957.     if (constructor_block -> explicit_constructor_invocation_opt)
  1958.     {
  1959.         this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1960.         super_call = constructor_block -> explicit_constructor_invocation_opt -> SuperCallCast();
  1961.     }
  1962.     else if (super_type)
  1963.     {
  1964.         LexStream::TokenIndex loc = block_body -> LeftToken();
  1965.         super_call                            = compilation_unit -> ast_pool -> GenSuperCall();
  1966.         super_call -> base_opt                = NULL;
  1967.         super_call -> dot_token_opt           = loc;
  1968.         super_call -> super_token             = loc;
  1969.         super_call -> left_parenthesis_token  = loc;
  1970.         super_call -> right_parenthesis_token = loc;
  1971.         super_call -> semicolon_token         = loc;
  1972.  
  1973.         constructor_block -> explicit_constructor_invocation_opt = super_call;
  1974.  
  1975.         if (super_type -> IsInner() && (! this_type -> CanAccess(super_type -> ContainingType())))
  1976.         {
  1977.             ReportSemError(SemanticError::ENCLOSING_INSTANCE_NOT_ACCESSIBLE,
  1978.                            constructor_declaration -> constructor_declarator -> LeftToken(),
  1979.                            constructor_declaration -> constructor_declarator -> RightToken(),
  1980.                            super_type -> ContainingType() -> ContainingPackage() -> PackageName(),
  1981.                            super_type -> ContainingType() -> ExternalName());
  1982.         }
  1983.     }
  1984.  
  1985.     //
  1986.     // If the constructor starts with an explicit_constructor_invocation, either
  1987.     // one specified by the user or generated, we process it and set up the proper
  1988.     // local environment, if appropriate...
  1989.     //
  1990.     if (constructor_block -> explicit_constructor_invocation_opt)
  1991.     {
  1992.         //
  1993.         // If we are processing a local constructor, set up the generated environment...
  1994.         //
  1995.         if (this_type -> IsLocal())
  1996.         {
  1997.             LocalSymbolTable().Pop();
  1998.  
  1999.             assert(this_method -> LocalConstructor() && (! this_method -> IsGeneratedLocalConstructor()));
  2000.  
  2001.             LocalSymbolTable().Push(this_method -> LocalConstructor() -> block_symbol -> Table());
  2002.         }
  2003.  
  2004.             if (this_call)
  2005.             {
  2006.                 this_call -> is_reachable = true;
  2007.                 ProcessThisCall(this_call);
  2008.             }
  2009.             else
  2010.             {
  2011.                 assert(super_call);
  2012.  
  2013.                 super_call -> is_reachable = true;
  2014.                 ProcessSuperCall(super_call);
  2015.             }
  2016.  
  2017.         //
  2018.         // If we are processing a local constructor, restore its original environment...
  2019.         //
  2020.         if (this_type -> IsLocal())
  2021.         {
  2022.             LocalSymbolTable().Pop();
  2023.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2024.         }
  2025.     }
  2026.  
  2027.     if (! (body_reachable || (constructor_block -> explicit_constructor_invocation_opt &&
  2028.                               constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())))
  2029.     {
  2030.         ReportSemError(SemanticError::UNREACHABLE_CONSTRUCTOR_BODY,
  2031.                        constructor_declaration -> LeftToken(),
  2032.                        constructor_declaration -> RightToken());
  2033.     }
  2034.  
  2035.     //
  2036.     // Guess that the number of elements will not exceed the number of statements.
  2037.     //
  2038.     int table_size = block_body -> NumStatements();
  2039.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  2040.     block -> max_variable_index = this_method -> block_symbol -> max_variable_index;
  2041.     LocalSymbolTable().Push(block -> Table());
  2042.  
  2043.     block_body -> is_reachable = true;
  2044.     block_body -> block_symbol = block;
  2045.     block_body -> nesting_level = LocalBlockStack().Size();
  2046.     LocalBlockStack().Push(block_body);
  2047.  
  2048.     ProcessBlockStatements(block_body);
  2049.  
  2050.     if (block_body -> can_complete_normally)
  2051.     {
  2052.         AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  2053.         return_statement -> return_token = block_body -> right_brace_token;
  2054.         return_statement -> expression_opt = NULL;
  2055.         return_statement -> semicolon_token = block_body -> right_brace_token;
  2056.         return_statement -> is_reachable = true;
  2057.         block_body -> can_complete_normally = false;
  2058.         block_body -> AddStatement(return_statement);
  2059.     }
  2060.  
  2061.     constructor_block -> can_complete_normally = block_body -> can_complete_normally;
  2062.  
  2063.     LocalBlockStack().Pop();
  2064.     LocalSymbolTable().Pop();
  2065.  
  2066.     //
  2067.     // Update the local variable info for the main block associated with this constructor.
  2068.     //
  2069.     if (this_method -> block_symbol -> max_variable_index < block -> max_variable_index)
  2070.         this_method -> block_symbol -> max_variable_index = block -> max_variable_index;
  2071.  
  2072.     block -> CompressSpace(); // space optimization
  2073.  
  2074.     return;
  2075. }
  2076.  
  2077.  
  2078. void Semantic::ProcessExecutableBodies(SemanticEnvironment *environment, AstClassBody *class_body)
  2079. {
  2080.     state_stack.Push(environment);
  2081.     TypeSymbol *this_type = ThisType();
  2082.  
  2083.     assert(this_type -> HeaderProcessed());
  2084.     assert(this_type -> ConstructorMembersProcessed());
  2085.     assert(this_type -> MethodMembersProcessed());
  2086.     assert(this_type -> FieldMembersProcessed());
  2087.  
  2088.     ThisVariable() = NULL; // All variable declarations have already been processed
  2089.  
  2090.     //
  2091.     // Compute the set of instance final variables declared by the user in this type
  2092.     // as well as the set of instance final variables that have not yet been initialized.
  2093.     //
  2094.     Tuple<VariableSymbol *> finals(this_type -> NumVariableSymbols()),
  2095.                             unassigned_finals(this_type -> NumVariableSymbols());
  2096.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2097.     {
  2098.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2099.         if (variable_symbol -> ACC_FINAL() && variable_symbol -> declarator)
  2100.         {
  2101.             finals.Next() = variable_symbol;
  2102.  
  2103.             if (! variable_symbol -> IsDefinitelyAssigned())
  2104.                 unassigned_finals.Next() = variable_symbol;
  2105.         }
  2106.     }
  2107.  
  2108.     AstBlock *last_block_body = (class_body -> NumBlocks() > 0 ? class_body -> Block(class_body -> NumBlocks() - 1)
  2109.                                                                : (AstBlock *) NULL);
  2110.     if (class_body -> NumConstructors() == 0)
  2111.     {
  2112.         //
  2113.         // Issue an error for each unassigned final.
  2114.         //
  2115.         for (int k = 0; k < unassigned_finals.Length(); k++)
  2116.         {
  2117.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2118.                            unassigned_finals[k] -> declarator -> LeftToken(),
  2119.                            unassigned_finals[k] -> declarator -> RightToken());
  2120.         }
  2121.  
  2122.         //
  2123.         // Process the body of the default constructor, if there is one.
  2124.         // (An anonymous class does not yet have a default constructor at this point.)
  2125.         //
  2126.         AstConstructorDeclaration *constructor_decl = class_body -> default_constructor;
  2127.         if (constructor_decl)
  2128.         {
  2129.             ThisMethod() = constructor_decl -> constructor_symbol;
  2130.  
  2131.             LocalSymbolTable().Push(ThisMethod() -> block_symbol -> Table());
  2132.             LocalBlockStack().max_size = 0;
  2133.             ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2134.             LocalSymbolTable().Pop();
  2135.             ThisMethod() -> max_block_depth = LocalBlockStack().max_size;
  2136.         }
  2137.     }
  2138.     else
  2139.     {
  2140.         for (int i = 0; i < class_body -> NumConstructors(); i++)
  2141.         {
  2142.             AstConstructorDeclaration *constructor_decl = class_body -> Constructor(i);
  2143.  
  2144.             ThisMethod() = constructor_decl -> constructor_symbol;
  2145.             MethodSymbol *this_method = ThisMethod();
  2146.             if (this_method)
  2147.             {
  2148.                 for (int l = 0; l < this_method -> NumFormalParameters(); l++)
  2149.                 {
  2150.                     VariableSymbol *parm = this_method -> FormalParameter(l);
  2151.                     AstVariableDeclaratorId *name = parm -> declarator -> variable_declarator_name;
  2152.  
  2153.                     SemanticEnvironment *where_found;
  2154.                     Tuple<VariableSymbol *> variables_found(2);
  2155.                     SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2156.                                                    parm -> Identity(),
  2157.                                                    name -> identifier_token);
  2158.                     VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2159.                     if (symbol && symbol -> IsLocal())
  2160.                     {
  2161.                         ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2162.                                        name -> identifier_token,
  2163.                                        name -> identifier_token,
  2164.                                        parm -> Name());
  2165.                     }
  2166.                 }
  2167.  
  2168.                 AstConstructorBlock *constructor_block = constructor_decl -> constructor_body;
  2169.                 if (constructor_block -> explicit_constructor_invocation_opt &&
  2170.                     constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())
  2171.                 {
  2172.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2173.                         unassigned_finals[j] -> MarkDefinitelyAssigned();
  2174.                 }
  2175.                 else
  2176.                 {
  2177.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2178.                         unassigned_finals[j] -> MarkNotDefinitelyAssigned();
  2179.                 }
  2180.  
  2181.                 LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2182.                 LocalBlockStack().max_size = 0;
  2183.  
  2184.                 int start_num_errors = NumErrors();
  2185.                 ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2186.  
  2187.                 LocalSymbolTable().Pop();
  2188.                 this_method -> max_block_depth = LocalBlockStack().max_size;
  2189.  
  2190.                 if (NumErrors() == start_num_errors)
  2191.                     DefiniteConstructorBody(constructor_decl, finals);
  2192.  
  2193.                 for (int k = 0; k < unassigned_finals.Length(); k++)
  2194.                 {
  2195.                     VariableSymbol *variable_symbol = unassigned_finals[k];
  2196.                     if (! variable_symbol -> IsDefinitelyAssigned())
  2197.                     {
  2198.                         ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE_IN_CONSTRUCTOR,
  2199.                                        constructor_decl -> LeftToken(),
  2200.                                        constructor_decl -> RightToken(),
  2201.                                        variable_symbol -> Name());
  2202.                     }
  2203.                 }
  2204.             }
  2205.         }
  2206.  
  2207.         for (int l = 0; l < this_type -> NumPrivateAccessConstructors(); l++)
  2208.         {
  2209.             ThisMethod() = this_type -> PrivateAccessConstructor(l);
  2210.             MethodSymbol *this_method = ThisMethod();
  2211.             AstConstructorDeclaration *constructor_decl = (AstConstructorDeclaration *)
  2212.                                                           this_method -> method_or_constructor_declaration;
  2213.  
  2214.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2215.             LocalBlockStack().max_size = 0;
  2216.             ProcessConstructorBody(constructor_decl, true);
  2217.             LocalSymbolTable().Pop();
  2218.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2219.         }
  2220.  
  2221.         ConstructorCycleChecker cycle_checker(class_body);
  2222.     }
  2223.  
  2224.     for (int j = 0; j < class_body -> NumMethods(); j++)
  2225.     {
  2226.         AstMethodDeclaration *method_decl = class_body -> Method(j);
  2227.  
  2228.         ThisMethod() = method_decl -> method_symbol;
  2229.         MethodSymbol *this_method = ThisMethod();
  2230.         if (this_method)
  2231.         {
  2232.             //
  2233.             // TODO: Confirm that this new test is indeed necessary. In 1.0, a more restricted test was used...
  2234.             //
  2235.             for (int i = 0; i < this_method -> NumFormalParameters(); i++)
  2236.             {
  2237.                 VariableSymbol *parm = this_method -> FormalParameter(i);
  2238.                 AstVariableDeclaratorId *name = parm -> declarator -> variable_declarator_name;
  2239.  
  2240.                 SemanticEnvironment *where_found;
  2241.                 Tuple<VariableSymbol *> variables_found(2);
  2242.                 SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2243.                                                parm -> Identity(),
  2244.                                                name -> identifier_token);
  2245.                 VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2246.                 if (symbol && symbol -> IsLocal())
  2247.                 {
  2248.                     ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2249.                                    name -> identifier_token,
  2250.                                    name -> identifier_token,
  2251.                                    parm -> Name());
  2252.                 }
  2253.             }
  2254.  
  2255.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2256.             LocalBlockStack().max_size = 0;
  2257.  
  2258.             int start_num_errors = NumErrors();
  2259.             ProcessMethodBody(method_decl);
  2260.  
  2261.             LocalSymbolTable().Pop();
  2262.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2263.  
  2264.             if (NumErrors() == start_num_errors)
  2265.                 DefiniteMethodBody(method_decl, finals);
  2266.         }
  2267.     }
  2268.  
  2269.     //
  2270.     // Mark all instance variables and constructor parameters final.
  2271.     //
  2272.     for (int i = 0; i <  this_type -> NumConstructorParameters(); i++)
  2273.         this_type -> ConstructorParameter(i) -> SetACC_FINAL();
  2274.  
  2275.     for (int l = 0; l <  this_type -> NumEnclosingInstances(); l++)
  2276.         this_type -> EnclosingInstance(l) -> SetACC_FINAL();
  2277.  
  2278.     //
  2279.     // We are done with all the methods, indicate that there is no method
  2280.     // being currently compiled in this environment.
  2281.     //
  2282.     ThisMethod() = NULL;
  2283.  
  2284.     //
  2285.     // Recursively process all inner types
  2286.     //
  2287.     for (int m = 0; m < class_body -> NumNestedClasses(); m++)
  2288.     {
  2289.         AstClassDeclaration *class_declaration = class_body -> NestedClass(m);
  2290.         if (class_declaration -> semantic_environment)
  2291.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2292.     }
  2293.  
  2294.     for (int n = 0; n < class_body -> NumNestedInterfaces(); n++)
  2295.     {
  2296.         if (class_body -> NestedInterface(n) -> semantic_environment)
  2297.             ProcessExecutableBodies(class_body -> NestedInterface(n));
  2298.     }
  2299.  
  2300.     state_stack.Pop();
  2301.  
  2302.     return;
  2303. }
  2304.  
  2305.  
  2306. void Semantic::ProcessExecutableBodies(AstInterfaceDeclaration *interface_declaration)
  2307. {
  2308.     state_stack.Push(interface_declaration -> semantic_environment);
  2309.     TypeSymbol *this_type = ThisType();
  2310.  
  2311.     assert(this_type -> HeaderProcessed());
  2312.     assert(this_type -> MethodMembersProcessed());
  2313.     assert(this_type -> FieldMembersProcessed());
  2314.  
  2315.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2316.     {
  2317.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2318.         if (! variable_symbol -> IsDefinitelyAssigned())
  2319.         {
  2320.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2321.                            variable_symbol -> declarator -> LeftToken(),
  2322.                            variable_symbol -> declarator -> RightToken());
  2323.         }
  2324.     }
  2325.  
  2326.     //
  2327.     // Recursively process all inner types
  2328.     //
  2329.     for (int m = 0; m < interface_declaration -> NumNestedClasses(); m++)
  2330.     {
  2331.         AstClassDeclaration *class_declaration = interface_declaration -> NestedClass(m);
  2332.         if (class_declaration -> semantic_environment)
  2333.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2334.     }
  2335.  
  2336.     for (int n = 0; n < interface_declaration -> NumNestedInterfaces(); n++)
  2337.     {
  2338.         if (interface_declaration -> NestedInterface(n) -> semantic_environment)
  2339.             ProcessExecutableBodies(interface_declaration -> NestedInterface(n));
  2340.     }
  2341.  
  2342.     state_stack.Pop();
  2343.  
  2344.     return;
  2345. }
  2346.